// excerpts from http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)

#pragma once

#include "noncopyable.h"
#include <functional>

namespace learnmuduo
{

class EventLoop;

///
/// A selectable I/O channel.
///
/// This class doesn't own the file descriptor.
/// The file descriptor could be a socket,
/// an eventfd, a timerfd, or a signalfd
class Channel : noncopyable {
public:
  typedef std::function<void()> EventCallback;

  Channel(EventLoop *loop, int fd);

  void handleEvent();
  void setReadCallback(const EventCallback &cb) { readCallback_ = cb; }
  void setWriteCallback(const EventCallback &cb) { writeCallback_ = cb; }
  void setErrorCallback(const EventCallback &cb) { errorCallback_ = cb; }

  int fd() const { return fd_; } // 返回文件描述符
  int events() const { return events_; } // 返回当前关注事件
  void set_revents(int revt) { revents_ = revt; }  // 设置实际发生的事件
  bool isNoneEvent() const { return events_ == kNoneEvent; } // 判断是否不关心事件

  void enableReading() { // 判断是否不关心事件
    events_ |= kReadEvent; // 在 events_ 已有的关注事件基础上，再“打开”读事件的开关，而不会影响其他已经设置好的事件标志
    update();
  }

  // for Poller
  int index() { return index_; } // 返回在pollfd数组中的索引
  void set_index(int idx) { index_ = idx; } // 设置索引

  EventLoop *ownerLoop() { return loop_; } // 返回所属EventLoop

private:
  void update(); // 通知EventLoop更新Channel

  static const int kNoneEvent; // 无事件常量
  static const int kReadEvent; // 读事件常量
  static const int kWriteEvent; // 写事件常量

  EventLoop *loop_; // 所属EventLoop
  const int fd_; // 维护的文件描述符
  int events_; // 关心的IO事件，由用户设置
  int revents_; // 目前活动的事件，由`EventLoop/Poller`设置
  int index_; // used by Poller.

  EventCallback readCallback_;
  EventCallback writeCallback_;
  EventCallback errorCallback_;
};
} // namespace learnmuduo
